package cc.rengu.igas.momp.core.service.trans;

import cc.rengu.igas.momp.common.constant.CommonConstant;
import cc.rengu.igas.momp.common.dao.McMchntInfoMapper;
import cc.rengu.igas.momp.common.dao.MompTMMcFundInfoMapper;
import cc.rengu.igas.momp.common.dao.impl.McMchntInfoMapperImpl;
import cc.rengu.igas.momp.common.dao.impl.MompTMMcFundInfoMapperImpl;
import cc.rengu.igas.momp.common.entity.*;
import cc.rengu.igas.momp.common.enums.*;
import cc.rengu.igas.momp.common.util.CommonMessageCheck;
import cc.rengu.igas.momp.common.util.McInfoDbOperation;
import cc.rengu.igas.momp.facade.bean.MchntInfoBean;
import cc.rengu.igas.momp.facade.request.MchntJoinJointMcRequest;
import cc.rengu.igas.momp.facade.response.MchntJoinJointMcResponse;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.base.StringUtil;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 商户参与联和营销活动接口实现
 *
 * @author liujinan
 * @version 1.0.0
 * @date 2020/6/17
 */
public class MchntJoinJointMcService extends RadpService {

    @Override
    protected int bizInit(String s) {
        return CommonConstant.PROCESS_SUCCESS;
    }

    @Override
    protected int bizProcess(String s, int i) {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            MchntJoinJointMcRequest mchntJoinJointMcRequest = new MchntJoinJointMcRequest();
            ConvertUtil.convertOutput(mchntJoinJointMcRequest);

            MchntJoinJointMcResponse mchntJoinJointMcResponse = new MchntJoinJointMcResponse();
            mchntJoinJointMcResponse.setHeader(mchntJoinJointMcRequest.getHeader());
            BizResponse<MchntJoinJointMcResponse> bizResponse = new BizResponse<>();
            bizResponse.setResult(mchntJoinJointMcResponse);

            String instId = mchntJoinJointMcRequest.getHeader().getInstId();
            String queryId = mchntJoinJointMcRequest.getQueryType();
            String queryType = mchntJoinJointMcRequest.getQueryType();
            String queryRole = mchntJoinJointMcRequest.getQueryRole();
            String mcNo = mchntJoinJointMcRequest.getQueryRole();
//            MchntInfoBean mchntInfo = mchntJoinJointMcRequest.getMchntInfo();

            rglog.info("机构<{}>的商户参与联和营销活动<{}>操作流程开始", instId, mcNo);

            //公共报文检查
            CommonMessageCheck.checkBizMessageHeader(queryType, queryId, queryRole, rglog);
            //接口请求报文检查
            checkRequestField(mchntJoinJointMcRequest);

            // 服务调用
            BizResponse<MchntJoinJointMcResponse> bizResponseNew = mchntJoinJointMc(mchntJoinJointMcRequest, mchntJoinJointMcResponse, xmlTreeUtil);

            ConvertUtil.convertInput(bizResponseNew.getResult());

        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
                xmlTreeUtil.setXmlTreeStringValue(CommonConstant.KEY_RESPDESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
                xmlTreeUtil.setXmlTreeStringValue(CommonConstant.KEY_RESPDESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e));
            }
        }

        return CommonConstant.PROCESS_SUCCESS;
    }

    @Override
    protected int bizTerminate(String s) {
        return CommonConstant.PROCESS_SUCCESS;
    }

    /**
     * 检查接口请求报文
     *
     * @param mchntJoinJointMcRequest 请求数据
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2020/6/17 22:10
     */
    private void checkRequestField(MchntJoinJointMcRequest mchntJoinJointMcRequest) {

        String queryId = mchntJoinJointMcRequest.getQueryType();
        String queryType = mchntJoinJointMcRequest.getQueryType();
        String queryOrgId = mchntJoinJointMcRequest.getQueryType();
        String queryRole = mchntJoinJointMcRequest.getQueryRole();
        String mcNo = mchntJoinJointMcRequest.getQueryRole();
        MchntInfoBean mchntInfo = mchntJoinJointMcRequest.getMchntInfo();

        if (null == queryId || CommonConstant.EMPTY_STRING.equals(queryId) || null == queryType || CommonConstant.EMPTY_STRING.equals(queryType) ||
                null == queryOrgId || CommonConstant.EMPTY_STRING.equals(queryOrgId) || null == queryRole || CommonConstant.EMPTY_STRING.equals(queryRole) ||
                null == mcNo || CommonConstant.EMPTY_STRING.equals(mcNo) || null == mchntInfo || CommonConstant.EMPTY_STRING.equals(mchntInfo)) {
            rglog.error("接口请求报文检验失败,存在必填请求字段为空,请核实!");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }
    }

    /**
     * 商户参与联和营销活动
     *
     * @param mchntJoinJointMcRequest  商户参与联和营销活动接口请求对象
     * @param mchntJoinJointMcResponse 商户参与联和营销活动接口应答对象
     * @param xmlTreeUtil              内部XML树
     * @return cc.rengu.oltp.service.model.BizResponse<cc.rengu.igas.momp.facade.response.MchntMcPublishResponse> 减免类活动发布接口应答对象
     * @throws BizException 异常信息
     * @author liujinan
     * @date 2020/6/17 16:59
     */
    private BizResponse<MchntJoinJointMcResponse> mchntJoinJointMc(MchntJoinJointMcRequest mchntJoinJointMcRequest, MchntJoinJointMcResponse mchntJoinJointMcResponse, XmlTreeUtil xmlTreeUtil)
            throws Exception {

        BizResponse<MchntJoinJointMcResponse> bizResponse = new BizResponse<>();
        // 查询主体所属机构 变更为 查询主体
        String oprId = mchntJoinJointMcRequest.getQueryId();
        String instId = mchntJoinJointMcRequest.getHeader().getInstId();
        String queryType = mchntJoinJointMcRequest.getQueryType();
        String queryRole = mchntJoinJointMcRequest.getQueryRole();
        String mcNo = mchntJoinJointMcRequest.getMcNo();
        String mcStatus = null, sponsor = null;
        MchntInfoBean mchntInfo = mchntJoinJointMcRequest.getMchntInfo();

        //判断用户的查询类型
        //商户人员操作
        if (QueryTypeEnum.MCHNT_QYERY_TYPE.getQueryTypeCode().equals(queryType)) {
            //判断是否打款
            MompTMMcFundInfoMapper tmMcFundInfoMapper = new MompTMMcFundInfoMapperImpl();
            List<MompTMMcFundInfo> MompTMMcFundInfoList = tmMcFundInfoMapper.selectMompTMMcFundInfoByInstIdAndMcNoAndDescByCreateTime(instId, mcNo, oprId, queryType);
            if (MompTMMcFundInfoList == null || MompTMMcFundInfoList.size() == 0) {
                //没有打款记录，异常
                rglog.info("机构<{}> 商户<{}> 营销活动<{}> 没有打款记录,不接受打款成功通知，异常！", instId, oprId, mcNo);
                throw new BizException(RespCodeEnum.WRONG_MC_FUND_INFO_ERROR.getRespCode(), RespCodeEnum.WRONG_MC_FUND_INFO_ERROR.getRespDesc());
            } else {
                //存在打款记录,判断最新打款记录的打款状态
                MompTMMcFundInfo lastMompTMMcFundInfo = MompTMMcFundInfoList.get(CommonConstant.ZERO);
                if (CommonConstant.ZERO_COMMON_CONSTANT.equals(lastMompTMMcFundInfo.getFundStatus())) {
                    //已成功打款
                    rglog.info("机构<{}> 商户<{}> 营销活动<{}> 已打款成功,打款流水号<{}> 流程继续！", instId, oprId, mcNo, lastMompTMMcFundInfo.getRecordIndex());
                } else {
                    //没有打款记录，异常
                    rglog.info("机构<{}> 商户<{}> 营销活动<{}> 打款失败,打款流水号<{}> 不接受打款成功通知，异常！", instId, oprId, mcNo, lastMompTMMcFundInfo.getRecordIndex());
                    throw new BizException(RespCodeEnum.WRONG_MC_FUND_INFO_ERROR.getRespCode(), RespCodeEnum.WRONG_MC_FUND_INFO_ERROR.getRespDesc());
                }
            }

            //根据营销活动号获取营销活动类型
            String mcType = mcNo.substring(2, 4);
            if (McTypeEnum.REDUCTION_FIXED_AMOUNT.getMcTypeCode().equals(mcType) ||
                    McTypeEnum.REDUCTION_RANDOM_AMOUNT.getMcTypeCode().equals(mcType) ||
                    McTypeEnum.REDUCTION_FIXED_RATE.getMcTypeCode().equals(mcType) ||
                    McTypeEnum.REDUCTION_RANDOM_RATE.getMcTypeCode().equals(mcType)) {
                //查询正式表数据
                rglog.info("查询机构<{}>的减免类营销活动<{}>的正式表表数据", instId, mcNo);
                TMMcMoneyOffInfo tmMcMoneyOffInfo = (TMMcMoneyOffInfo) McInfoDbOperation.getMcInfo(rglog, instId, mcNo, TableNameEnum.T_M_MC_MO_INFO.getTableNameCode());
                //查询临时表数据
                rglog.info("查询机构<{}>的减免类营销活动<{}>的临时表表数据", instId, mcNo);
                TMPlatBizTmp moneyOffTMPlatBizTmp = McInfoDbOperation.getTmpMcInfo(rglog, instId, mcNo, TableNameEnum.T_M_MC_MO_INFO.getTableNameCode());
                if ((null == tmMcMoneyOffInfo || null == moneyOffTMPlatBizTmp)) {
                    rglog.error("获取机构<{}>的营销活动编号<{}>的营销活动基本信息异常!", instId, mcNo);
                    throw new BizException(RespCodeEnum.GET_MC_LIST_ERROR.getRespCode(), RespCodeEnum.GET_MC_LIST_ERROR.getRespDesc());
                }
                //出资方
                sponsor = tmMcMoneyOffInfo.getSponsor();
                //营销活动状态mcStatus
                mcStatus = tmMcMoneyOffInfo.getMcStatus();
            } else if (McTypeEnum.COUPON_ALL.getMcTypeCode().equals(mcType) ||
                    McTypeEnum.COUPON_FREE.getMcTypeCode().equals(mcType) ||
                    McTypeEnum.COUPON_PAID.getMcTypeCode().equals(mcType)) {
                //查询正式表数据
                rglog.info("查询机构<{}>的卡券类营销活动<{}>的正式表表数据", instId, mcNo);
                TMMcCouponInfo tmMcCouponInfo = (TMMcCouponInfo) McInfoDbOperation.getMcInfo(rglog, instId, mcNo, TableNameEnum.T_M_MC_CP_INFO.getTableNameCode());
                //查询临时表数据
                rglog.info("查询机构<{}>的卡券类营销活动<{}>的临时表表数据", instId, mcNo);
                TMPlatBizTmp couponTMPlatBizTmp = McInfoDbOperation.getTmpMcInfo(rglog, instId, mcNo, TableNameEnum.T_M_MC_CP_INFO.getTableNameCode());
                if ((null == tmMcCouponInfo && null == couponTMPlatBizTmp)) {
                    rglog.error("获取机构<{}>的营销活动编号<{}>的营销活动基本信息异常!", instId, mcNo);
                    throw new BizException(RespCodeEnum.GET_MC_LIST_ERROR.getRespCode(), RespCodeEnum.GET_MC_LIST_ERROR.getRespDesc());
                }
                //出资方
                sponsor = tmMcCouponInfo.getSponsor();
                //营销活动状态mcStatus
                mcStatus = tmMcCouponInfo.getMcStatus();
            } else {
                rglog.error("机构<{}>的营销活动编号<{}>的营销活动类型<{}>不支持!", instId, mcNo, mcType);
                throw new BizException(RespCodeEnum.NOT_SUPPORTED_MC_TYPE_ERROR.getRespCode(), RespCodeEnum.NOT_SUPPORTED_MC_TYPE_ERROR.getRespDesc());
            }

            //如果出资方不是银商联合的,异常
            if (!CommonConstant.SPONSOR_MIXED.equals(sponsor)) {
                rglog.error("机构<{}>的营销活动编号<{}>的出资方为<{}>,不允许商户加入联合营销", instId, mcNo, sponsor);
                throw new BizException(RespCodeEnum.WRONG_SPONSOR_TO_JOINMC_ERROR.getRespCode(), RespCodeEnum.WRONG_SPONSOR_TO_JOINMC_ERROR.getRespDesc());
            }
            //营销活动状态不是未发布或进行中,不允许参加
            if (!McStatusEnum.PROGRESSING.getMcStatusCode().equals(mcStatus) &&
                    !McStatusEnum.NOT_PUBLISHED.getMcStatusCode().equals(mcStatus)) {
                rglog.error("机构<{}>的营销活动编号<{}>的活动状态为<{}>,不允许商户加入联合营销", instId, mcNo, mcStatus);
                throw new BizException(RespCodeEnum.WRONG_MCSTATUS_TO_JOINMC_ERROR.getRespCode(), RespCodeEnum.WRONG_MCSTATUS_TO_JOINMC_ERROR.getRespDesc());
            }
            //查询营销活动商户信息 ,联合营销活动只能是商户,不能是商圈
            rglog.error("机构<{}>的营销活动<{}>的商户信息查询...", instId, mcNo);
            McMchntInfoMapper mcMchntInfoMapper = new McMchntInfoMapperImpl();
            List<TMMcMchntInfo> mchntInfoList = mcMchntInfoMapper.selectMcMchntInfoList(instId, mcNo);
            if (null == mchntInfoList || mchntInfoList.isEmpty()) {
                rglog.error("机构<{}>的营销活动<{}>的商户信息查询失败!", instId, mcNo);
                throw new BizException(RespCodeEnum.GET_MC_MCHNT_INFO_ERROR.getRespCode(), RespCodeEnum.GET_MC_MCHNT_INFO_ERROR.getRespDesc());
            }
            //商户列表
            List<String> mchntNoList = mchntInfoList.stream().map(TMMcMchntInfo::getMchntNo).collect(Collectors.toList());
            //判断当前商户是否属于营销活动商户中
            if (!mchntNoList.contains(mchntInfo.getMchntNo())) {
                rglog.error("机构<{}>的营销活动编号<{}>不包括当前商户,不允许加入营销活动,当前商户<{}>", instId, mcNo, mcStatus, mchntInfo.getMchntNo());
                throw new BizException(RespCodeEnum.WRONG_MCHNT_TO_JOINMC_ERROR.getRespCode(), RespCodeEnum.WRONG_MCHNT_TO_JOINMC_ERROR.getRespDesc());
            }

            for (TMMcMchntInfo tmMcMchntInfo : mchntInfoList) {
                if (tmMcMchntInfo.getMchntNo().equals(mchntInfo.getMchntNo())) {
                    String exitFlag = tmMcMchntInfo.getExitFlag();
                    String newMchntFlag = tmMcMchntInfo.getNewMchntFlag();

                    rglog.info("商户营销活动退出标志:<{}>,新增商户标志<{}>", exitFlag, newMchntFlag);

                    if (CommonConstant.MC_NOT_EXIT_FLAG.equals(exitFlag) && CommonConstant.MCHNT_NEW_FLAG.equals(newMchntFlag)) {
                        rglog.error("商户已经加入营销活动,目前为未退出优惠状态!");
                        throw new BizException(RespCodeEnum.WRONG_MCHNT_ISALREADY_INMC_ERROR.getRespCode(), RespCodeEnum.WRONG_MCHNT_ISALREADY_INMC_ERROR.getRespDesc());
                    }

                    if (CommonConstant.MC_EXIT_FLAG.equals(exitFlag) && CommonConstant.MCHNT_NEW_FLAG.equals(newMchntFlag)) {
                        rglog.error("商户已加入此营销活动,且优惠已结束，不允许再次加入!");
                        throw new BizException(RespCodeEnum.WRONG_MCHNT_ISALREADY_INMCOVER_ERROR.getRespCode(), RespCodeEnum.WRONG_MCHNT_ISALREADY_INMCOVER_ERROR.getRespDesc());
                    }

                    if (CommonConstant.MC_NOT_EXIT_FLAG.equals(exitFlag) && CommonConstant.MCHNT_OLD_FLAG.equals(newMchntFlag)) {
                        rglog.error("商户状态为：未退出优惠状态，且 新增商户标志为存量商户 ，状态异常!");
                        throw new BizException(RespCodeEnum.WRONG_MCSTATUS_TO_JOINMC_ERROR.getRespCode(), RespCodeEnum.WRONG_MCSTATUS_TO_JOINMC_ERROR.getRespDesc());
                    }

                    tmMcMchntInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
                    tmMcMchntInfo.setExitFlag(CommonConstant.MC_NOT_EXIT_FLAG);
                    tmMcMchntInfo.setNewMchntFlag(CommonConstant.MCHNT_NEW_FLAG);
                    //更改商户在营销活动商户信息表中的exit_flag为未退出优惠,newMchntFlag为新增商户
                    rglog.info("更新商户营销活动退出标志:<{}>,新增商户标志<{}>", tmMcMchntInfo.getExitFlag(), tmMcMchntInfo.getNewMchntFlag());
                    int updateReturnCode = mcMchntInfoMapper.updateExitFlagAndNewMchntFlag(tmMcMchntInfo);
                    if (updateReturnCode != 0) {
                        rglog.error("根据主键更新营销活动商户信息表T_M_MC_MCHNT_INFO失败！");
                        throw new BizException(RespCodeEnum.WRONG_UPDATEMCMCHNT_ERROR.getRespCode(), RespCodeEnum.WRONG_UPDATEMCMCHNT_ERROR.getRespDesc());
                    }
                    break;
                }
            }
        } else {
            // 非商户人员无权限操作数据
            rglog.error("当前<{}>角色的查询用户<{}>无权限操作数据!", queryRole, queryType);
            throw new BizException(RespCodeEnum.NO_AUTHORIZATION_TO_OPER_ERROR.getRespCode(), RespCodeEnum.NO_AUTHORIZATION_TO_OPER_ERROR.getRespDesc());
        }

        bizResponse.setRspSysId(ChannelEnum.MOMP.getChannelType());
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());

        mchntJoinJointMcResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        mchntJoinJointMcResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(mchntJoinJointMcResponse);

        return bizResponse;
    }
}
